#pragma once

#include "../Atom.hpp"
#include "DLDataRange.hpp"

namespace terms {
	namespace dl {
		template <typename L=std::string, typename I=std::string, typename C=std::string, typename R=std::string>
		class DLLiteral 
			: public DLDataRange<L, I, C, R>, Atom
		{
		private:
			L _literal;

		public:
			DLLiteral(const L &literal)
				: _literal(literal)
			{
			}

		public:
			const L &
			get_literal() const
			{
				return _literal;
			}

		public:
			virtual DLTermOrder
			get_type_order() const
			{
				return DLTermOrder::LITERAL;
			}

		public:
			virtual std::size_t
			hash() const
			{
				return std::hash<L>()(_literal);
			}

		public:	 
			virtual bool
			operator==(const DLTerm<L, I, C, R> &term) const
			{
				if (this->get_type_order() == term.get_type_order()) {
					const DLLiteral<L, I, C, R> *other = dynamic_cast<const DLLiteral<L, I, C, R> *>(&term);
					return this->get_literal() == other->get_literal();
				} else {
					return false;
				}
			}

		public:
			virtual bool
			operator <(const DLTerm<L, I, C, R> &term) const
			{
				if (this->get_type_order() < term.get_type_order()) {
					return true;
				} else if (this->get_type_order() == term.get_type_order()) {
					const DLLiteral<L, I, C, R> *other = dynamic_cast<const DLLiteral<L, I, C, R> *>(&term);
					return this->get_literal() < other->get_literal();
				} else {
					return false;
				}	
			}

		public:
			virtual std::string
			to_string() const
			{
				return std::to_string(get_literal());
			}

		public:
			virtual bool
			is_top_datatype() const
			{
				return false;
			}

		};
	}	
}	
